package pb;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by gamy on 2017/8/3.
 */
public class PBField {

    final static public String PB_TYPE_UINT = "uint32";
    final static public String PB_TYPE_TEXT = "string";
    final static public String PB_TYPE_FLOAT = "float";
    final static public String PB_TYPE_INT = "int32";

    final static public String SQL_TYPE_INT = "INT";
    final static public String SQL_TYPE_UINT = "INT UNSIGNED";
    final static public String SQL_TYPE_TEXT = "TEXT";
    final static public String SQL_TYPE_FLOAT = "FLOAT";


    final static public String PB_TYPE_REPEATED = "repeated";
    final static public String PB_TYPE_REQUIRED = "required";
    final static public String PB_TYPE_OPTIONAL = "optional";

    private static final String FIELD_TYPE_PATTEN = new String("[optional|repeated|required]\\s+([a-zA-Z0-9|_]+)");
    private static final String FIELD_NAME_PATTEN = new String("[optional|repeated|required]\\s+[a-zA-Z0-9|]+\\s+([a-zA-Z0-9|_]+)");
    private static final String FIELD_SQLTYPE_PATTEN = new String("sql_type='([^,|']+)'");
    private static final String FIELD_SQLEXT_PATTEN = new String("sql_ext='([^,|']+)'");

    private static final String SQL_EXT = "sql_ext";
    private static final String SQL_TYPE = "sql_type";


    String name;
    String type;
    boolean isSqlField;
    String sqlType;
    String sqlExt;
    String lineStr;
    boolean notNull;


    public static boolean isFieldLine(String lineString) {
        if (lineString != null && (lineString.contains(PB_TYPE_OPTIONAL) || lineString.contains(PB_TYPE_REPEATED) || lineString.contains(PB_TYPE_REQUIRED))) {
            return true;
        }
        return false;
    }


    private String getMatchString(String lineStr, String patten)
    {
        Matcher matcher = Pattern.compile(patten).matcher(lineStr);
        if (matcher.find()) {
            String name = matcher.group(1);
            return name;
        }
        return "";
    }

    public PBField(String lineStr) {
        this.lineStr = lineStr;

        this.name = getMatchString(lineStr, FIELD_NAME_PATTEN);
        this.type = getMatchString(lineStr, FIELD_TYPE_PATTEN);

        this.sqlType = getMatchString(lineStr, FIELD_SQLTYPE_PATTEN);
        this.sqlExt = getMatchString(lineStr, FIELD_SQLEXT_PATTEN);

    }


    private String getDefaultValue(){
        if (this.sqlExt.length() == 0){
            String typeStr = "";
            if (this.sqlType.length() != 0){
                typeStr = this.sqlType.toLowerCase();
            }else {
                typeStr = this.type.toLowerCase();
            }

            if (typeStr.contains("int") || typeStr.contains("float") || typeStr.contains("double") || typeStr.contains("byte")){
                return "NOT NULL DEFAULT 0";
            }

            if (typeStr.contains("char")){
                return "NOT NULL DEFAULT ''";
            }

            if (typeStr.contains("text") || typeStr.contains("string")){
                return "";
            }
        }
        return "";
    }


    public String getSqlStament() {
        String tab = "\t\t\t";
        String st = "\t" + name;
        st += tab + (this.sqlType.length() != 0 ? this.sqlType : this.type);
        String defaultValue = getDefaultValue();
        st += defaultValue.length() != 0 ? (" " + defaultValue +" ") : "";
        st += this.sqlExt.length() != 0 ? (tab +this.sqlExt) : "";

        st = st.replace(PB_TYPE_UINT, SQL_TYPE_UINT).replace(PB_TYPE_FLOAT, SQL_TYPE_FLOAT).
                replace(PB_TYPE_TEXT, SQL_TYPE_TEXT).replace(PB_TYPE_INT, SQL_TYPE_INT);
        return st;
    }

    @Override
    public String toString() {
        return "PBField{" +
                "name='" + name + '\'' +
                ", type='" + type + '\'' +
                ", isSqlField=" + isSqlField +
                ", sqlType='" + sqlType + '\'' +
                ", sqlExt='" + sqlExt + '\'' +
                ", lineStr='" + lineStr + '\'' +
                ", notNull=" + notNull +
                '}';
    }
}
